#include "attack.hpp"

#include "vision.hpp"

#include "../attack_prediction.hpp"
#include "../game_config.hpp"
#include "../game_display.hpp"
#include "../game_events.hpp"
#include "../game_preferences.hpp"
#include "../gettext.hpp"
#include "../log.hpp"
#include "../map.hpp"
#include "../mouse_handler_base.hpp"
#include "../random.hpp"
#include "../replay.hpp"
#include "../resources.hpp"
#include "../statistics.hpp"
#include "../team.hpp"
#include "../tod_manager.hpp"
#include "../unit.hpp"
#include "../unit_abilities.hpp"
#include "../unit_display.hpp"
#include "../unit_map.hpp"
#include "../whiteboard/manager.hpp"
#include "../wml_exception.hpp"

static lg::log_domain log_engine("engine");
#define DBG_NG LOG_STREAM(debug, log_engine)
#define LOG_NG LOG_STREAM(info, log_engine)
#define ERR_NG LOG_STREAM(err, log_engine)

static lg::log_domain log_config("config");
#define LOG_CF LOG_STREAM(info, log_config)

battle_context_unit_stats::battle_context_unit_stats(const unit& u,
		const map_location& u_loc, int u_attack_num, bool attacking,
		const unit& opp, const map_location& opp_loc,
		const attack_type* opp_weapon, const unit_map& units) :
weapon(NULL),
attack_num(u_attack_num),
is_attacker(attacking),
is_poisoned(u.get_state(unit::STATE_POISONED)),
is_slowed(u.get_state(unit::STATE_SLOWED)),
slows(false),
drains(false),
petrifies(false),
plagues(false),
poisons(false),
backstab_pos(false),
swarm(false),
firststrike(false),
experience(u.experience()),
max_experience(u.max_experience()),
level(u.level()),
rounds(1),
hp(0),
max_hp(u.max_hitpoints()),
chance_to_hit(0),
damage(0),
slow_damage(0),
drain_percent(0),
drain_constant(0),
num_blows(0),
swarm_min(0),
swarm_max(0),
plague_type()
{
	if (attack_num >= 0)
	{
		weapon = &u.attacks()[attack_num];
	}
	if (u.hitpoints() < 0)
	{
		LOG_CF << "Unit with " << u.hitpoints() << " hitpoints found, set to 0 for damage calculations\n";
		hp = 0;
	}
	else if (u.hitpoints() > u.max_hitpoints())
	{
		hp = u.max_hitpoints();
	}
	else
	{
		hp = u.hitpoints();
	}

	if (weapon)
	{
		weapon->set_specials_context(u_loc, opp_loc, attacking, opp_weapon);
		if (opp_weapon)
			opp_weapon->set_specials_context(opp_loc, u_loc, !attacking, weapon);
		bool not_living = opp.get_state("not_living");
		slows = weapon->get_special_bool("slow");
		drains = !not_living && weapon->get_special_bool("drains");
		petrifies = weapon->get_special_bool("petrifies");
		poisons = !not_living && weapon->get_special_bool("poison") && !opp.get_state(unit::STATE_POISONED);
		backstab_pos = is_attacker && backstab_check(u_loc, opp_loc, units, *resources::teams);
		rounds = weapon->get_specials("berserk").highest("value", 1).first;
		firststrike = weapon->get_special_bool("firststrike");

		unit_ability_list plague_specials = weapon->get_specials("plague");

	}
}
